<html>
<head><meta charset="utf-8"><title>constraints on the design · project-safe-transmute · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/index.html">project-safe-transmute</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html">constraints on the design</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="183353652"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183353652" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183353652">(Dec 13 2019 at 12:21)</a>:</h4>
<p>AFAICT there is no agreement on which problem this feature should solve, nor what are the constraints on the design (e.g. should this be a zero-cost abstraction, should this result in an explosion of impls, etc.). It would probably make sense to start by collecting examples and constraints before designing a proposed solution.</p>



<a name="183354963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183354963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183354963">(Dec 13 2019 at 12:40)</a>:</h4>
<p>I think this is a good idea. Here's my first stab at this:<br>
<strong>Problems</strong>:</p>
<ul>
<li>Main issues: Converting between bytes (i.e., <code>&amp;[u8]</code>) to types and in general casting between two arbitrary types. The reason I call out the casting between <code>&amp;[u8]</code> and a some other type as a special case is because my impression is that this is the most common use case (e.g., you have some buffer of bytes and would like to view pieces of that buffer as bytes). </li>
<li>Side issue: some types require runtime checks to verify a particular invariant (e.g., a byte can be a bool only if it is 0 or 1). Ideally a solution would allow for casting to and from such types.</li>
<li>Side issue: safe reading of union fields </li>
</ul>
<p><strong>constraints</strong>:</p>
<ul>
<li>Should be a "zero-cost" abstraction (i.e., runtime checks are only performed when strictly necessary). </li>
<li>Should not cause an explosion of trait impls that could negatively impact compiler performance</li>
<li>Should be flexible enough to support main issue above and if not now at least later also support the side issues above</li>
<li>Should allow differentiation between types that can be viewed as well formed bytes (i.e., no UB) and types that can constructed from arbitrary bytes. </li>
<li>should be automatically implementable for custom types and allow casting between types even no matter where those types are defined.</li>
</ul>



<a name="183355186"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183355186" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183355186">(Dec 13 2019 at 12:43)</a>:</h4>
<p>The Compatible&lt;T&gt; RFC also lists some constraints on the design: <a href="https://gist.github.com/gnzlbg/4ee5a49cc3053d8d20fddb04bc546000#design-goals-and-constraints" target="_blank" title="https://gist.github.com/gnzlbg/4ee5a49cc3053d8d20fddb04bc546000#design-goals-and-constraints">https://gist.github.com/gnzlbg/4ee5a49cc3053d8d20fddb04bc546000#design-goals-and-constraints</a></p>
<blockquote>
<p>These design goals and constraints are derived from the examples below:</p>
<ul>
<li>
<p><strong>performance</strong>: users that do not care about performance can just deconstruct a value into its fields and use those to construct a new value without using any unsafe code. Going from one value to another in a single (or no) memcpy is the main advantage of this feature.</p>
</li>
<li>
<p><strong>complete</strong>: it must be possible to encode safety invariant using this feature, if<br>
        * transmute::&lt;T, U&gt; is provably safe, using safe_transmute<br>
        * transmute::&lt;T, U&gt; is only safe for some values of U, using try_safe_transmute</p>
</li>
<li>
<p><strong>sound</strong>: safe_transmute&lt;T, U&gt; must not type check for a T-U-pair for which a transmute is unsound.</p>
</li>
<li>
<p><strong>consistent</strong>: if safe_transmute::&lt;T, U&gt; is safe, it must be possible to replace that with transmute::&lt;T, U&gt;.</p>
</li>
<li>
<p><strong>ergonomic</strong>: the feature should be more ergonomic than mem::transmute. In particular, if transmute::&lt;T, U&gt; is provably safe, then safe_transmute::&lt;T, U&gt; must just work.</p>
</li>
</ul>
</blockquote>



<a name="183355516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183355516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183355516">(Dec 13 2019 at 12:47)</a>:</h4>
<p>For example, IIUC, the safe transmute pre-RFCs violate most of these constraints.</p>



<a name="183355551"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183355551" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183355551">(Dec 13 2019 at 12:47)</a>:</h4>
<p>But by doing so the safe transmute pre-RFCs are able to do things that this RFC cannot.</p>



<a name="183355672"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183355672" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183355672">(Dec 13 2019 at 12:49)</a>:</h4>
<p>For example, with the safe transmute RFC you can transmute a <code>&amp;[u8]</code> to a <code>&amp;[u8; 16]</code>, but you can't replace that with an unsafe <code>transmute::&lt;&amp;[u8; 16], &amp;[u8]&gt;</code> call to avoid checks because the two types have different sizes.</p>



<a name="183355909"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183355909" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183355909">(Dec 13 2019 at 12:52)</a>:</h4>
<p>Just so we're on the same page, I think the RFC you posted is not fully correct when specifying the constraints that "safe-transmute-v2" proposes:</p>
<blockquote>
<p>unnecessarily require run-time checks, e.g. bool -&gt; #[repr(transparent)] struct Bool(bool)</p>
</blockquote>
<p>Because of inlining the example you provided does not actually require runtime checks. I think a more appropriate way to state this is that it relies on the optimizer to do the right thing. So far, I've only found one case where runtime checks were not correctly eliminated by the optimizer (which I stated above). I'm not saying this isn't an issue, but the way it's stated is misleading.</p>
<blockquote>
<p>ergonomics: many ""transmutes"" require multiple calls to the transmute methods, as opposed to plain transmute, e.g., bool -&gt; Bool requires two transmute operations.</p>
</blockquote>
<p>This is not true. The RFC provides a method that allows this to happen in one call (namely <code>cast</code>).</p>
<p>As for the other two constraints, I'm not sure I fully understand why those are a constraint on the design.</p>



<a name="183355939"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183355939" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183355939">(Dec 13 2019 at 12:52)</a>:</h4>
<blockquote>
<p>Because of inlining the example you provided does not actually require runtime checks</p>
</blockquote>
<p>In my constraint, this must be guaranteed, and not require run-time checks at any optimization level.</p>



<a name="183355993"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183355993" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183355993">(Dec 13 2019 at 12:53)</a>:</h4>
<p>That is, the constraint is that because this is a performance-only feature, such optimizations must be guaranteed and always apply.</p>



<a name="183356088"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356088" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356088">(Dec 13 2019 at 12:54)</a>:</h4>
<blockquote>
<blockquote>
<p>Because of inlining the example you provided does not actually require runtime checks</p>
</blockquote>
<p>In my constraint, this must be guaranteed, and not require run-time checks at any optimization level.</p>
</blockquote>
<p>That's fair. I think though that it's important to state that the "safe-transmute-v2" proposal fails at this _only_ when the optimizer is not able to optimize many of the const expressions away. The way it reads currently makes it sound like a runtime check will always be performed when that's simply not true.</p>



<a name="183356132"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356132" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356132">(Dec 13 2019 at 12:55)</a>:</h4>
<p>It also fails at this when LTO is disabled, when optimizations are disabled, when the inliner fails, etc.</p>



<a name="183356137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356137">(Dec 13 2019 at 12:55)</a>:</h4>
<p>i.e., the choice is between gurantee of no runtime checks vs. best effort no runtime checks _NOT_ between no runtime checks and runtime checks</p>



<a name="183356205"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356205" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356205">(Dec 13 2019 at 12:56)</a>:</h4>
<p>As mentioned, my constraint requires guaranteeing no runtime checks, ever. I couldn't find anywhere in the RFC of safe-transmute v2 that guarantee, so that's why I mentioned that it does not guarantee that.</p>



<a name="183356230"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356230" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356230">(Dec 13 2019 at 12:56)</a>:</h4>
<p>If the safe-transmute RFC is changed to guarantee that such run-time checks will never happen, then I can change that part.</p>



<a name="183356248"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356248" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356248">(Dec 13 2019 at 12:56)</a>:</h4>
<p>But I understood safe-transmute v2 to be "best-effort" in that regard.</p>



<a name="183356285"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356285" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356285">(Dec 13 2019 at 12:57)</a>:</h4>
<p>And the tests in godbolt are done within the same translation unit. More interesting tests would be when the FromBytes/ToBytes trait are implemented in different crates, the impls aren't <code>#[inline]</code>, and LTO is disabled.</p>



<a name="183356294"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356294" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356294">(Dec 13 2019 at 12:57)</a>:</h4>
<p>I think you're misunderstanding what I'm saying. What you're stating here is correct, but your analysis in the RFC reads differently. Your analysis reads as if the runtime checks will always be performed not that there is not hard guarantee that they won't be performed. I believe this to be very different</p>



<a name="183356365"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356365" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356365">(Dec 13 2019 at 12:58)</a>:</h4>
<p>My analysis reads that rustc will always generate code to perform the runtime checks, and whether this code is removed or not would depend on a best effort optimization in the backend that might or might not happen.</p>



<a name="183356373"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356373" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356373">(Dec 13 2019 at 12:58)</a>:</h4>
<p>I can try to word that in such a way that makes it clearer that those run-time checks can sometimes be removed by the backend.</p>



<a name="183356395"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356395" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356395">(Dec 13 2019 at 12:59)</a>:</h4>
<p>Yes that's all I'm stating. I think that would make it much clearer</p>



<a name="183356428"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356428" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356428">(Dec 13 2019 at 13:00)</a>:</h4>
<p>I've added a sentence to clarify that.</p>



<a name="183356561"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356561" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356561">(Dec 13 2019 at 13:01)</a>:</h4>
<p>Thanks, and thoughts on the ergonomics point? From the user's perspective, casting between two types is a single call to <code>cast</code>.</p>



<a name="183356639"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356639" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356639">(Dec 13 2019 at 13:02)</a>:</h4>
<p>I'm not sure I agree with your point that the proposal fails to provide an ergonomic ability to transmute</p>



<a name="183356663"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356663" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356663">(Dec 13 2019 at 13:02)</a>:</h4>
<p><span class="user-mention" data-user-id="224872">@Ryan Levick</span> how does that work for types with padding ?</p>



<a name="183356680"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356680" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356680">(Dec 13 2019 at 13:02)</a>:</h4>
<p>IIUC, that requires an implementation of <code>ToBytes</code> to exist</p>



<a name="183356730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356730">(Dec 13 2019 at 13:03)</a>:</h4>
<p>but that cannot exist for, e.g., <code>#[repr(C)] struct A { x: bool, y: u16 }</code>, and then you can't cast that to <code>#[repr(C)] struct B { x: Bool, y: u16 }</code></p>



<a name="183356888"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356888" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356888">(Dec 13 2019 at 13:05)</a>:</h4>
<p>Ah wait, that's a violation of the completeness constraint, not ergonomics.</p>



<a name="183356921"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183356921" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183356921">(Dec 13 2019 at 13:05)</a>:</h4>
<p>Yes, I was about to write that. And I agree with that point</p>



<a name="183357029"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357029" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357029">(Dec 13 2019 at 13:06)</a>:</h4>
<p>I believe that when the proposal doesn't fail on one of the other points, it does not fail on ergonomics</p>



<a name="183357137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357137">(Dec 13 2019 at 13:07)</a>:</h4>
<p>I'd also change the completeness point to reflect the example above ^^ and not the <code>bool</code> to <code>Bool</code> one currently in the document. While that might be technically true, I don't believe it captures why one should care like the example above does</p>



<a name="183357201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357201">(Dec 13 2019 at 13:08)</a>:</h4>
<p><span class="user-mention" data-user-id="224872">@Ryan Levick</span> yes you are right, ergonomics are fine</p>



<a name="183357228"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357228" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357228">(Dec 13 2019 at 13:08)</a>:</h4>
<p>It doesn't suffer from N x M, since you only need ~ N + M implementations, to go from/to <code>[u8]</code></p>



<a name="183357243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357243">(Dec 13 2019 at 13:09)</a>:</h4>
<p>That's the best that can be done AFAICT</p>



<a name="183357268"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357268" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357268">(Dec 13 2019 at 13:09)</a>:</h4>
<p>(by the way, it might be a good idea to get these two RFCs into the repo so we can collaborate through PRs as well). I'll need to convert the "safe-transmute-v2" pre-rfc into the RFC format so we can more easily compare</p>



<a name="183357276"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357276" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357276">(Dec 13 2019 at 13:09)</a>:</h4>
<p>sure I can send a PR</p>



<a name="183357281"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357281" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357281">(Dec 13 2019 at 13:09)</a>:</h4>
<p>the RFC is not ready though</p>



<a name="183357335"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357335" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357335">(Dec 13 2019 at 13:10)</a>:</h4>
<p>There are some degrees-of-freedom that some RFCs have, that I haven't been able to word as constraints</p>



<a name="183357344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357344">(Dec 13 2019 at 13:10)</a>:</h4>
<p>for example, <code>TryCompatible</code> has an associated error type</p>



<a name="183357368"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357368" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357368">(Dec 13 2019 at 13:10)</a>:</h4>
<p>That solves some problems that safe-transmute v2 has, like being able to express that some operations cannot fail by using <code>!</code></p>



<a name="183357373"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357373" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357373">(Dec 13 2019 at 13:10)</a>:</h4>
<p>But it introduces other problems</p>



<a name="183357389"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357389" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357389">(Dec 13 2019 at 13:11)</a>:</h4>
<blockquote>
<p>All alternatives discussed below require N x M trait impls.</p>
</blockquote>
<p>This is not true for the safe-transmute-v2 proposal</p>



<a name="183357391"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357391" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357391">(Dec 13 2019 at 13:11)</a>:</h4>
<p>Like it makes it impossible to provide something like <code>::cast</code></p>



<a name="183357623"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357623" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357623">(Dec 13 2019 at 13:14)</a>:</h4>
<p>A middle ground solution would be to only allow certain types as the associated type</p>



<a name="183357640"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357640" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357640">(Dec 13 2019 at 13:15)</a>:</h4>
<p>e.g. one can allow <code>!</code> or a specific Result type, by bounding the associated error type with a sealed trait that's only implemented for those two.</p>



<a name="183357664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357664">(Dec 13 2019 at 13:15)</a>:</h4>
<p>I believe the "safe-transmute-v2" proposal does better in terms of trait impls. Each type has at most 3 trait impls (FromAnyBytes, FromBytes and ToBytes). The "compatible" proposal requires each trait to have an unbounded number of impls for every type it can possibly be compatible with. Am I wrong in thinking this?</p>



<a name="183357720"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357720" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357720">(Dec 13 2019 at 13:16)</a>:</h4>
<p>Yes, you are wrong.</p>



<a name="183357727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357727">(Dec 13 2019 at 13:16)</a>:</h4>
<p>The compatible trait proposal only requires one trait impl, either <code>Compatible&lt;T&gt;</code> or <code>TryCompatible&lt;T&gt;</code>, per type.</p>



<a name="183357756"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357756" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357756">(Dec 13 2019 at 13:17)</a>:</h4>
<p>If <code>T</code> is <code>[u8]</code> then you can go to any type that's compatible with that</p>



<a name="183357855"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357855" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357855">(Dec 13 2019 at 13:18)</a>:</h4>
<p>For example, if you have a type <code>struct Foo([u8; 4]);</code> and implement <code>Foo: Compatible&lt;[u8; 4]&gt;</code>, and you have some other type <code>Bar</code> such that <code>[u8; 4]: Compatible&lt;Bar&gt;</code>, then you can go from <code>Foo</code> to <code>Bar</code>.</p>



<a name="183357889"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357889" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357889">(Dec 13 2019 at 13:19)</a>:</h4>
<p>Even though there is no <code>Foo: Compatible&lt;Bar&gt;</code> impl.</p>



<a name="183357982"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183357982" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183357982">(Dec 13 2019 at 13:20)</a>:</h4>
<p>I would not have imagined the type system was capable of following through all those relationships. I'm assuming you've tested this and it works?</p>



<a name="183358007"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358007" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358007">(Dec 13 2019 at 13:20)</a>:</h4>
<p>I asked in the chalk zulip, and they said that such a query is probably possible, similar queries exist</p>



<a name="183358048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358048">(Dec 13 2019 at 13:21)</a>:</h4>
<p>Is it currently possible? Because it should be explicitly noted that this would require changes to the type inferencer if that's the case</p>



<a name="183358050"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358050" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358050">(Dec 13 2019 at 13:21)</a>:</h4>
<p>They are unsure about how exactly formulate the query in a recursive way</p>



<a name="183358120"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358120" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358120">(Dec 13 2019 at 13:22)</a>:</h4>
<p>But since chalk is prolog-like, it must be possible to ask whether such a sequence exist</p>



<a name="183358146"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358146" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358146">(Dec 13 2019 at 13:22)</a>:</h4>
<p>It is noted that the meaning of <code>T: Compatible&lt;U&gt;</code> bound is special.</p>



<a name="183358158"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358158" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358158">(Dec 13 2019 at 13:22)</a>:</h4>
<p>And the precise definition of that trait query is noted in the RFC.</p>



<a name="183358176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358176">(Dec 13 2019 at 13:23)</a>:</h4>
<p>There's also the issue that it can result in non-deterministic lifetime bounds, unless there's some well-defined search order. Which IMO makes it a non-starter, even if no one will ever write a lifetime-dependent <code>Compatible</code> impl.</p>



<a name="183358191"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358191" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358191">(Dec 13 2019 at 13:23)</a>:</h4>
<p><span class="user-mention" data-user-id="116118">@Matthew Jasper</span> it is non-deterministic, but the RFC argues that it doesn't matter</p>



<a name="183358203"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358203" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358203">(Dec 13 2019 at 13:23)</a>:</h4>
<p>is that argument incorrect ?</p>



<a name="183358260"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358260" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358260">(Dec 13 2019 at 13:24)</a>:</h4>
<p>If you have a <code>transmute::&lt;T, U&gt;()</code>, for that to be safe, it suffices to exist a chain of transmutes from U to T that are safe</p>



<a name="183358266"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358266" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358266">(Dec 13 2019 at 13:24)</a>:</h4>
<p>if there are multiple chains, it doesn't really matter which one you pick</p>



<a name="183358282"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358282" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358282">(Dec 13 2019 at 13:24)</a>:</h4>
<p><span class="user-mention" data-user-id="132920">@gnzlbg</span> I'm not seeing where that's plainly stated. Can you point me to that?</p>



<a name="183358290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358290">(Dec 13 2019 at 13:24)</a>:</h4>
<p>In the trait query specification</p>



<a name="183358304"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358304" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358304">(Dec 13 2019 at 13:25)</a>:</h4>
<blockquote>
<p>Notice that multiple such sequences could exist, but it suffices that one exists for the query to be satisfied.</p>
</blockquote>



<a name="183358323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358323">(Dec 13 2019 at 13:25)</a>:</h4>
<p>There problem is that with lifetimes you don't know whether a sequence exists until it's too late.</p>



<a name="183358334"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358334" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358334">(Dec 13 2019 at 13:25)</a>:</h4>
<p>Ah sorry, I meant where it's plainly stated that the trait resolution is not currently possible but would need to be added to have this feature</p>



<a name="183358408"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358408" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358408">(Dec 13 2019 at 13:26)</a>:</h4>
<p>I see where it's implied if you're familiar with how things currently work, but it would be nice to have this spelled out explicitly</p>



<a name="183358424"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358424" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358424">(Dec 13 2019 at 13:26)</a>:</h4>
<p>In the drawbacks section, it does say "Complicates the trait system"</p>



<a name="183358455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358455">(Dec 13 2019 at 13:27)</a>:</h4>
<p>That section is obviously incomplete, somebody should expand on that, mentioning that a new kind of query with the semantics of the reference section have to be added, etc.</p>



<a name="183358462"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358462" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358462">(Dec 13 2019 at 13:27)</a>:</h4>
<blockquote>
<p>There problem is that with lifetimes you don't know whether a sequence exists until it's too late.</p>
</blockquote>
<p>Can you elaborate?</p>



<a name="183358470"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358470" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358470">(Dec 13 2019 at 13:27)</a>:</h4>
<p>Maybe an example would help making that clearer.</p>



<a name="183358530"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358530" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358530">(Dec 13 2019 at 13:28)</a>:</h4>
<p>(e.g. i'm imagining <code>impl&lt;'a, T, U&gt; Compatible&lt;&amp;'a U&gt; for &amp;'a T { } where T: Compatible&lt;U&gt;</code> but I don't see any big issues with that)</p>



<a name="183358607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358607">(Dec 13 2019 at 13:29)</a>:</h4>
<p>Maybe <code>impl&lt;'a, 'b, T, U&gt; Compatible&lt;&amp;'a U&gt; for &amp;'b T where T: Compatible&lt;U&gt;, 'b: 'a {}</code> ?</p>



<a name="183358926"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183358926" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183358926">(Dec 13 2019 at 13:33)</a>:</h4>
<p>So if there are impls like <code>Compatible&lt;&amp;'a U&gt; for &amp;'b U</code> and <code>Compatible&lt;U&gt; for U</code> then depending on the impl we choose converting <code>&amp;'0 U</code> to <code>&amp;'1 U</code> may require the regions to be equal, or only that one outlives the other. (It doesn't matter here due to variance, but that's besides the point).</p>



<a name="183359039"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359039" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359039">(Dec 13 2019 at 13:35)</a>:</h4>
<p><span class="user-mention" data-user-id="116118">@Matthew Jasper</span> I thought it would be the other way around</p>



<a name="183359092"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359092" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359092">(Dec 13 2019 at 13:35)</a>:</h4>
<p>If one writes <code>safe_transmute::&lt;&amp;'a U, &amp;'a U&gt;</code> then the regions are required to be equal, while if one does <code>safe_transmute::&lt;&amp;'a U, &amp;'b U&gt;</code> then one is required to out-live the other.</p>



<a name="183359142"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359142" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359142">(Dec 13 2019 at 13:36)</a>:</h4>
<p>You can link me to the Discussion in the Chalk Zulip you mentioned? It seems clear that this can be implemented without too much trouble, but I'm not sure it will be better for compiler performance than having N x M impls manifest in the program. The obvious way to do it (which side-steps all worries about degrading the neat properties Chalk has today) is to add a transitivity rule like <code>(?T : Compatible&lt;?U&gt;) :- (?T : Compatible&lt;?V&gt;), (?V : Compatible&lt;?U&gt;)</code>. But I worry that setting Chalk loose on this won't be particularly efficient, because Chalk enumerates answers to trait queries breadth-first. BFS is not great at finding paths between a specific pair of nodes quickly, and although it amortizes pretty well (assuming memoization, which Chalk obviously has) if you compute the reachability matrix of the whole graph, doing that would require (asymptotically) as much time and memory as generating all the N x M impls before going into trait solving.</p>



<a name="183359213"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359213" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359213">(Dec 13 2019 at 13:37)</a>:</h4>
<blockquote>
<p>If one writes safe_transmute::&lt;&amp;'a U, &amp;'a U&gt; then the regions are required to be equal, while if one does safe_transmute::&lt;&amp;'a U, &amp;'b U&gt; then one is required to out-live the other.</p>
</blockquote>
<p>I wouldn't expect the lifetimes to be dependent on with chain of trait impls is picked, but rather, for the lifetime requirements to constraint which chain of trait impls are valid. But maybe I'm misunderstanding the order in which lifetimes and traits are resolved ?</p>



<a name="183359289"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359289" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359289">(Dec 13 2019 at 13:38)</a>:</h4>
<p>I may have swapped them. Free lifetime inference is always the last part of type checking.</p>



<a name="183359362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359362">(Dec 13 2019 at 13:39)</a>:</h4>
<p><span class="user-mention" data-user-id="124289">@rkruppe</span> I kind of expect each type to have very few <code>Compatible</code> impls, and typically towards some type like a <code>[u8; N]</code> that "maximizes" how many safe transmutes they get for free</p>



<a name="183359420"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359420" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359420">(Dec 13 2019 at 13:40)</a>:</h4>
<p>So that's indeed quite bad due to what you said</p>



<a name="183359439"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359439" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359439">(Dec 13 2019 at 13:40)</a>:</h4>
<p>Once you reach such a type, there are many edges that must be visited to find the type you want to convert to</p>



<a name="183359446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359446">(Dec 13 2019 at 13:40)</a>:</h4>
<p>even if the conversion is only two graph edges away</p>



<a name="183359450"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359450" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359450">(Dec 13 2019 at 13:40)</a>:</h4>
<p>because these nodes in the middle have lots of edges</p>



<a name="183359473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359473">(Dec 13 2019 at 13:41)</a>:</h4>
<div class="codehilite"><pre><span></span><span class="n">TryCompatible</span><span class="o">&lt;&amp;</span><span class="p">[</span><span class="kt">u8</span><span class="p">;</span><span class="w"> </span><span class="p">{</span><span class="n">size_of</span>::<span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">()}]</span><span class="o">&gt;</span><span class="w"></span>
</pre></div>


<p>One benefit of <code>Compatible&lt;T&gt;</code> is that its future compatible with const generics. For the other RFC we would need to make the choice if we want to be dependent on const generics or not</p>



<a name="183359818"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183359818" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183359818">(Dec 13 2019 at 13:45)</a>:</h4>
<p><span class="user-mention" data-user-id="116118">@Matthew Jasper</span></p>
<blockquote>
<p>I may have swapped them. Free lifetime inference is always the last part of type checking.</p>
</blockquote>
<p>So I'm not sure how that would work. From the constraint, multiple chains might be valid, and each chain might have different life-time requirements, and that might impact lifetime inference later on, since there are multiple ways to infer a particular lifetime. I'm not sure if by that time it matters, e.g., if the two possibilities are that either one lifetime must outlive the other, or be independent, and both are "ok", then does it matter? And if only one is ok, the other cannot be inferred, right?</p>



<a name="183402089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183402089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183402089">(Dec 13 2019 at 21:24)</a>:</h4>
<p><span class="user-mention" data-user-id="224872">@Ryan Levick</span> I think that <code>bytemuck</code> actually hits most of your goals already, <em>except</em> that it is deliberately very conservative in the design and mostly doesn't tackle the issue of types with limited bit patterns. Such things could be added without changing the fundamental design though (one such extension to support limited bit pattern types is in PR review phase actually).</p>
<p>I think that a lot of the safe transmuting can be handled with marker traits to give what a type supports and then a small collection of trait bound free functions that do the work. This lets us leverage parametric generics as much as possible to do a lot of the hard thinking for us.</p>
<p>I would also like to add that transmuting <code>&amp;[u8]</code> to <code>&amp;T</code> seems to get mentioned a lot but it's not even the type of cast that was most requested before I made my crate. People were usually asking for slice to slice casting and owned to owned casting. I hope those casts can be remembered more often as we discuss.</p>



<a name="183544035"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183544035" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183544035">(Dec 16 2019 at 12:26)</a>:</h4>
<blockquote>
<p>I would also like to add that transmuting &amp;[u8] to &amp;T seems to get mentioned a lot but it's not even the type of cast that was most requested before I made my crate</p>
</blockquote>
<p>This is certainly interesting. The original use case I was coming from that prompted me to start the whole RFC process was one in which the programmer memcopies a large buffer (probably from the network) and then wants to safely view pieces of that buffer in a structured way. This is directly the <code>&amp;[u8]</code> to <code>&amp;T</code> use case. I see <code>&amp;[u8]</code> to <code>&amp;[T]</code> as a direct extension of that as well. </p>
<p>What are some of the high level use cases for <code>&amp;[T]</code> to <code>&amp;[U]</code> and <code>T</code> to <code>U</code> casting? I believe both proposals being discussed support these use cases, but I want to make sure I have a good understanding of the actual need for this.</p>



<a name="183546261"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183546261" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183546261">(Dec 16 2019 at 13:01)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> I also don't see a huge ton of difference between the "safe-transmute" pre-RFC and <code>bytemuck</code> (we only didn't mention it in the pre-RFC because we somehow missed it - we'll mention it in the RFC should we go this direction). I believe <code>bytemuck</code> simplifies by removing the following features which are available in the pre-RFC:</p>
<ul>
<li>No distinction between types that can be safely cast _from_ vs safely cast _to_. For instance, it's safe to cast to a type with padding and it's safe to cast from bool.</li>
<li>No derive mechanism</li>
<li>No fallible casting (e.g., casting to bool)</li>
</ul>



<a name="183562942"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183562942" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183562942">(Dec 16 2019 at 16:03)</a>:</h4>
<p>I first came to this general problem of safe transmutation because gfx-hal had a "cast_slice" operation that was actually really unsound, so I wrote a correct version. I stuffed it into my "bag of utils" crate and forgot about it for months until the lead of <a href="https://github.com/rust-secure-code/safety-dance" target="_blank" title="https://github.com/rust-secure-code/safety-dance">Safety Dance</a> saw it and said "actually you should put just that one thing in its own crate because people are out here casting slices all the time and getting it wrong all the time".</p>
<p>I've specifically seen people ask for:</p>
<ul>
<li><code>&amp;[u8]</code> to <code>&amp;[u32]</code>: This is what <code>gfx-hal</code> wanted, so that you can upload <code>include_bytes!</code> data as SPIRV</li>
<li><code>&amp;[T]</code> to <code>&amp;[u8]</code>: Another FFI problem, where C is accepting a <code>void*</code> and a length, so in Rust we kinda shrug and say "Well I guess we model that with letting the user pass <code>&amp;[u8]</code> for the C code to read?". Eg: for the GPU you might want to upload some huge list of <code>f32</code> vertex data but the C API is non-generic so it's on you to make it <code>&amp;[u8]</code> first.</li>
<li><code>&amp;[u8]</code> to <code>&amp;[i8]</code> or the reverse: Basically "c_char" has no default signed-ness to it so the signed-ness that we apply to it in rust isn't the same by platform, but really it doesn't matter and people just want to cast between the two forms.</li>
<li><code>__m128</code> to <code>[f32;4]</code> is super popular for SIMD work, obviously. You don't do it during your SIMD operations, but you do it to pack and unpack the data at the edges of the SIMD pipeline.</li>
<li><code>&amp;mut T</code> to <code>&amp;mut [u8]</code>: needed for randomization libraries such as <a href="https://docs.rs/getrandom/0.1.13/getrandom/fn.getrandom.html" target="_blank" title="https://docs.rs/getrandom/0.1.13/getrandom/fn.getrandom.html">getrandom</a> that accept a buffer to overwrite with random bytes .</li>
</ul>
<p>I didn't even put <code>&amp;[u8]</code> to <code>&amp;T</code> into <code>bytemuck</code> 1.0 because I guess I didn't talk to enough parsing people or something, but <em>also</em> that's just a mild specialization of a slice cast. For the first pass of my PNG parser, where I  probably would have used <code>&amp;[u8]</code> to <code>&amp;T</code>, I just wrote</p>
<div class="codehilite"><pre><span></span><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="n">here</span><span class="p">,</span><span class="w"> </span><span class="n">more</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">more</span><span class="p">.</span><span class="n">split_at</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">arr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">cast_slice</span>::<span class="o">&lt;</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">;</span><span class="mi">4</span><span class="p">]</span><span class="o">&gt;</span><span class="p">(</span><span class="n">slice</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span><span class="w"></span>
</pre></div>


<p>to pull out <code>[u8;4]</code> arrays from the data steam. Perfectly ergonomic? No, definitely not, but it does show that slice casting is probably the most "fundamental" of all the casts. SimonSapin actually threw a <code>&amp;[u8]</code> to <code>&amp;T</code> PR at me the day they saw my crate, so that's in 1.1 now.</p>
<p>As to your bullet points:
* For "cast from X into bytes", I considered making a trait for that which is a parent trait of <code>Pod</code>, similar to how <code>Zeroable</code> gets its own sub-trait. People often want to just zero a thing as cheap initialization, so I split if off as its own ability. However, when I asked folks, "hey what if there was a trait for linear memory that was totally initialized? That could be a lesser contract than <code>Pod</code>." people said "what's the point?" and I said "Well it'd let you have this one special method <code>as_bytes</code> where you can turn any <code>&amp;T</code> into <code>&amp;[u8]</code>". Not a <em>single</em> person I talked to was impressed with the concept. No one thought that it was worth having a dedicated trait, so I just dropped the concept for lack of demand. It's certainly something you could fit into the design if anyone actually does care.
* Deriving it all is really, really hard without compiler support :P Though someone added a Zeroable derive. Of course I'd like to see more happen here, 
* Fallible casting actually has an <a href="https://github.com/Lokathor/bytemuck/pull/12" target="_blank" title="https://github.com/Lokathor/bytemuck/pull/12">open PR right now</a> if you want to see one possible design. It's really focused on enums and enum-likes just because of how the person who wrote it wants to use it. They need it for somewhere deep inside some huge mostly-C++ codebase where Rust and C++ talk to each other. The PR's particular design allows <code>bool</code>, but it <em>doesn't</em> allow for <code>char</code> or <code>NonZeroI32</code>. Again, it's largely an artifact of wanting to be fast (minimal checks) while also being absolutely correct without fail, and in the absence of compiler support we end up just covering the cases that we know we can do correctly as a crate. I think that with compiler support this would become a lot easier. On the other hand, I asked on the <code>#design</code> channel of the Official Discord a few weeks ago, "hey what about the idea of compiler support for having some bits of some amount and then being able to ask the compiler 'if I wanted to put these bits within some enum or other limited bit pattern type, what value would they be in that type?" and at the time people essentially said "that sounds so niche I don't think we'd bother to spend the time to implement that ability". So hopefully this project group can make the issue seem worth the time.</p>
<p>(This post got super long but I hope I was clear about everything.)</p>



<a name="183567213"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183567213" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183567213">(Dec 16 2019 at 16:46)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> Thanks for the clarifications! Question: is the limitation that some types aren't Pod but could be casted to (e.g., bool) acceptable to you? The reason we introduced the <code>ToBytes</code> wasn't because we thought it's interesting to turn a  type into bytes, but because it's sometimes necessary to distinguish between types that are Pods (using your definition for what that is) and types that aren't but reading them always gives you well defined bytes</p>



<a name="183570114"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183570114" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183570114">(Dec 16 2019 at 17:14)</a>:</h4>
<p>I have nothing fundamentally against the idea. People just told me no one cared, so I skipped over it. I could even put it into <code>bytemuck</code> as a proof of concept if you'd like to see it set up in practice.</p>
<p>Though I'll note: for going from <code>u8</code> to <code>bool</code> it should just be a <code>TryFrom</code> impl. Any "do a cast but we have to perform a validity check" should just use the existing TryFrom trait as much as possible. That's what it's there for. And it makes the way you can use a type very discoverable when you look in the docs.</p>



<a name="183570658"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183570658" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183570658">(Dec 16 2019 at 17:21)</a>:</h4>
<p>(though, without const generics, the only thing <code>bytemuck</code> could do with a "LinearInitialized" marker trait is some sort of <code>view_bytes</code> function for <code>&amp;T</code> to <code>&amp;[u8]</code>. It'd probably get really complicated if you wanted to do owned to owned casting.)</p>



<a name="183575885"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183575885" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183575885">(Dec 16 2019 at 18:25)</a>:</h4>
<p>I'm not sure I agree with the TryFrom recommendation</p>



<a name="183575933"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183575933" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183575933">(Dec 16 2019 at 18:26)</a>:</h4>
<p>TryFrom does a "value preserving" conversion, while transmute re-interprets some memory as being of a different type, and is "bit pattern preserving"</p>



<a name="183576053"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183576053" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183576053">(Dec 16 2019 at 18:27)</a>:</h4>
<p>For some types, like going from a <code>u8</code> to a <code>bool</code>, both things have the same semantics, but this is not true for all types.</p>



<a name="183576202"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183576202" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183576202">(Dec 16 2019 at 18:29)</a>:</h4>
<p>So if both operations are different and make sense exposing, then we need two ways to expose them, and then the question becomes whether for types for which both operations mean the same thing, both should still be exposed or not.</p>



<a name="183578173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183578173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183578173">(Dec 16 2019 at 18:51)</a>:</h4>
<p>That's fair. For other types it might be a lot less correct for TryFrom to be used.</p>



<a name="183582694"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183582694" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183582694">(Dec 16 2019 at 19:38)</a>:</h4>
<p>Agreed; <code>TryFrom</code>is for semantic conversions that might change the memory values, and it doesn't guarantee that it'll do an allocation-free reinterpretation of memory.</p>



<a name="183594557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183594557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183594557">(Dec 16 2019 at 21:48)</a>:</h4>
<p>This touches a bit on a tangential issue, which is how can we encourage implementations of whatever mechanism we use to be "allocation-free" (or more generally, just free)</p>



<a name="183594601"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183594601" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183594601">(Dec 16 2019 at 21:49)</a>:</h4>
<p>I think one invariant that kind of enforces this is to allow replacing whatever mechanism we use with an <code>unsafe { transmute::&lt;T, U&gt;(x) }</code></p>



<a name="183594625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183594625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183594625">(Dec 16 2019 at 21:49)</a>:</h4>
<p>But that feels to restrictive, since it require both <code>T</code> and <code>U</code> to have the same size</p>



<a name="183594682"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183594682" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183594682">(Dec 16 2019 at 21:50)</a>:</h4>
<p>(e.g. it won't work for <code>&amp;[T]</code> to <code>&amp;[T; N]</code> because both references have different sizes)</p>



<a name="183595162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183595162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183595162">(Dec 16 2019 at 21:54)</a>:</h4>
<p>It seems fair to classify &amp;[T] to &amp;U as a different "type" of transmute which we can simply support separately from non-referencing T to U.</p>



<a name="183640325"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183640325" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183640325">(Dec 17 2019 at 11:42)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> to me it feels more like a coercion than a transmute</p>



<a name="183640342"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183640342" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183640342">(Dec 17 2019 at 11:43)</a>:</h4>
<p>We are coercing a fat pointer <code>&amp;[T]</code> into a thin pointer, e.g., <code>&amp;[T; N]</code>.</p>



<a name="183640456"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183640456" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183640456">(Dec 17 2019 at 11:44)</a>:</h4>
<p>I think there is also a third case: coercing <code>&amp;[T]</code> to <code>&amp;[U]</code>, where the coercion is not just a "bitwise" copy, but it might involve changing the bits of, e.g., the length of the slice (e.g. for going from <code>&amp;[u16]</code> to <code>&amp;[u8]</code>).</p>



<a name="183640641"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183640641" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183640641">(Dec 17 2019 at 11:47)</a>:</h4>
<p>The main problem with doing "some work" is that the work can fail. I'm not sure if this is true for going from <code>&amp;[u16]</code> to <code>&amp;[u8]</code>, but one thing that could happen is that this coercion could fail if, e.g., doubling the length overflows <code>isize</code>, but whether that can actually happen might depend on which limits we impose to the lengths of allocations (e.g. if an allocation can at most be <code>isize</code> bytes, such overflow cannot happen). So there might be some subtle interaction between coercions that do some work, and unspecified parts of the Rust abstract machine, like the largest size of a Rust object or allocation.</p>



<a name="183657606"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183657606" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183657606">(Dec 17 2019 at 15:18)</a>:</h4>
<p>that's already a general limit on slices (no more than isize bytes), but I guess it's not an allocation limit in general. Still, if you have any slice in rust it's span is isize::MAX bytes or less</p>



<a name="183657676"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/constraints%20on%20the%20design/near/183657676" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/constraints.20on.20the.20design.html#183657676">(Dec 17 2019 at 15:19)</a>:</h4>
<p>But yeah, that's why I like "casting", because people understand fuzzily that a cast is "free, or maybe a tiny amount of work"</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>